package com.system.boot.rbac.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.system.api.SuperInterface;
import com.system.api.rbac.entity.po.SysMenu;
import com.system.api.rbac.entity.po.SysPermission;
import com.system.api.rbac.entity.po.SysUserAccount;
import com.system.api.rbac.entity.po.SysUserRoleRelation;
import com.system.boot.rbac.mapper.UserAccountMapper;
import com.system.boot.rbac.mapper.UserRoleRelationMapper;
import com.system.boot.rbac.service.UserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yang.common.core.constant.SystemConstant;
import org.yang.common.core.enums.UserStatusEnum;
import org.yang.common.core.exception.BaseException;
import org.yang.common.utils.EncryptUtil;
import org.yang.database.orm.entity.BaseModel;
import org.yang.database.orm.entity.BaseQuery;

import java.util.List;
import java.util.Optional;


/**
 * @author: lslands
 * @description:
 * @version：v1.0
 * @date: 2024/6/2 22:33
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserAccountMapper, SysUserAccount> implements UserService {

    private final UserRoleRelationMapper userRoleRelationMapper;
    private final PasswordEncoder passwordEncoder;


    @Override
    public void isExists(Long companyId, String filed, String params) throws BaseException {
        boolean exists = baseMapper.getExistsByParams(companyId,filed,params);
        if(exists){
            throw new BaseException(BaseException.REPEAT,params);
        }
    }

    @Override
    public List<String> getNameByUserId(List<Long> userIds) throws BaseException {
        if(userIds.isEmpty()){
            throw new BaseException(BaseException.NULL);
        }
        return baseMapper.selectNameByUserIds(userIds);
    }

    @Override
    public String getNameByUserId(Long userId) throws BaseException {
        SysUserAccount sysUserAccount = baseMapper.selectOne(new LambdaQueryWrapper<SysUserAccount>()
                .select(SysUserAccount::getUsername).select(BaseModel::getId));
        return sysUserAccount.getUsername();
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public int handInsert(SysUserAccount record, List<Long> roleIds) throws BaseException {
        this.calibrate(record);
        String pwd = Optional.ofNullable(EncryptUtil.aesDecryptForFront(record.getPassword(), SystemConstant.KEY_DES))
                .orElseThrow(() -> new BaseException("解密异常"));
        record.setPassword(passwordEncoder.encode(pwd));
        if(roleIds.isEmpty()){
            record.setEnabled(UserStatusEnum.UNAUTHORIZED.getValue());
        }
        baseMapper.insert(record);
        if(!roleIds.isEmpty()){
            List<SysUserRoleRelation> roleRelations = roleIds.stream()
                    .map(x -> {
                        SysUserRoleRelation build = SysUserRoleRelation.builder()
                                .userId(record.getId()).roleId(x).build();
                        build.setCreatedBy(record.getCreatedBy());
                        return build;
                    }).toList();
            userRoleRelationMapper.insertBach(roleRelations);
        }
        return 1;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public int handUpdateById(SysUserAccount record, List<Long> roleIds) throws BaseException {
        return 0;
    }

    @Override
    public Page<SysUserAccount> getPage(BaseQuery query, SysUserAccount record) throws BaseException {
        Page<SysUserAccount> page= new Page<>(query.getCurrent(), query.getSize());
        LambdaQueryWrapper<SysUserAccount> wrapper = new LambdaQueryWrapper<SysUserAccount>()
                .select(BaseModel::getId, SysUserAccount::getUsername, SysUserAccount::getNickname, SysUserAccount::getPhone,
                        SysUserAccount::getEmail, BaseModel::getEnabled, SysUserAccount::getAvatar)
                .like(StringUtils.isNotBlank(record.getUsername()),SysUserAccount::getUsername, record.getUsername())
                .eq(SysUserAccount::getCompanyId, record.getCompanyId())
                .eq(null!=record.getEnabled(),BaseModel::getEnabled, record.getEnabled())
                .orderByDesc(BaseModel::getId);
        return baseMapper.selectPage(page,wrapper);
    }


    /**
     * 校验账户/电话/邮箱
     * @param record 对象
     * @throws BaseException 重复异常
     */
    private void calibrate(SysUserAccount record) throws BaseException{
        this.isExists(record.getCompanyId(),"username",record.getUsername());
        this.isExists(record.getCompanyId(),"phone",record.getPhone());
        if(StringUtils.isNotBlank(record.getEmail())){
            this.isExists(record.getCompanyId(),"email",record.getEmail());
        }
    }


}
